package public

import (
	"context"
	"fmt"
	"goProject/api/auth"
	"goProject/cfg"
	"goProject/db"
	"goProject/table"
	"net/http"
	"time"

	"gitee.com/ruige_fun/util/rlog"

	"gorm.io/gorm"

	"gitee.com/ruige_fun/util/std"
	"github.com/kataras/iris/v12"
)

type pRegister struct {
	Code string `json:"code" validate:"required,min=6,max=255"`
	User string `json:"user" validate:"required,min=6,max=20"`
	Pwd  string `json:"pwd" validate:"required,min=6,max=255"`
}

func register(c iris.Context) {
	var p pRegister
	err := c.ReadBody(&p)
	if err != nil {
		c.JSON(std.NewResp(http.StatusBadRequest, "参数校验失败", nil, nil))
		return
	}
	if v := db.RedisToken.Get(context.Background(), fmt.Sprint(cfg.Config.Main.ProjectName+"_register_blacklist_", p.User, "_", c.RemoteAddr())).Val(); v != "" {
		c.JSON(std.NewResp(http.StatusBadRequest, "距离上次注册时间过短，请稍后重试。", nil, nil))
		return
	}
	var u table.User
	err = db.MySQL.Where("`username` = ?", p.User).First(&u).Error
	if err == nil {
		c.JSON(std.NewResp(http.StatusBadRequest, "用户名已存在", nil, nil))
		return
	}
	err = db.MySQL.Transaction(func(tx *gorm.DB) error {
		var rCode table.RegisterCode
		err2 := tx.Where("`code` = ?", p.Code).First(&rCode).Error
		if err2 != nil {
			db.RedisToken.Set(context.Background(), fmt.Sprint(cfg.Config.Main.ProjectName+"_register_blacklist_", c.RemoteAddr()), time.Now().Unix()+60, time.Second*60) //黑名单
			return fmt.Errorf("注册码不存在，请 60 秒后重试。")
		}
		if rCode.UserID != 0 {
			db.RedisToken.Set(context.Background(), fmt.Sprint(cfg.Config.Main.ProjectName+"_register_blacklist_", c.RemoteAddr()), time.Now().Unix()+60, time.Second*60) //黑名单
			return fmt.Errorf("注册码已被使用过，请 60 秒后重试。")
		}
		var newUser = table.User{
			Username: p.User,
			Password: auth.CypherPassword(p.User, p.Pwd),
		}
		err2 = tx.Create(&newUser).Error
		if err2 != nil {
			return fmt.Errorf("系统出错，注册失败，请稍后重试。")
		}
		err2 = tx.Create(&table.Profile{
			ID:     newUser.ID,
			RoleID: rCode.RoleID,
		}).Error
		if err2 != nil {
			return fmt.Errorf("系统出错，注册失败，请稍后重试。")
		}
		rCode.UserID = newUser.ID
		rCode.RegisterAt = newUser.CreatedAt
		err2 = tx.Select("UserID", "RegisterAt").Save(&rCode).Error
		if err2 != nil {
			return fmt.Errorf("系统出错，注册失败，请稍后重试。")
		}
		db.RedisToken.Set(context.Background(), fmt.Sprint(cfg.Config.Main.ProjectName+"_register_blacklist_", c.RemoteAddr()), time.Now().Unix()+60, time.Second*60) //黑名单
		rlog.Success(c.RemoteAddr(), "注册了账号：", newUser, rCode)
		return nil
	})
	if err != nil {
		c.JSON(std.NewResp(http.StatusInternalServerError, fmt.Sprint(err), nil, nil))
		return
	}
	c.JSON(std.NewResp(http.StatusOK, "", nil, nil))
}
